package org.dromara.pay.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.business.constant.BusinessConstants;
import org.dromara.business.domain.Coupon;
import org.dromara.business.domain.Goods;
import org.dromara.business.domain.GoodsOrder;
import org.dromara.business.domain.vo.BusinessConfigVo;
import org.dromara.business.service.*;
import org.dromara.business.util.WxSubscribeUtil;
import org.dromara.common.core.constant.UserConstants;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.WxOrderService;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.websocket.utils.WebSocketUtils;
import org.dromara.pay.domain.TopUp;
import org.dromara.system.domain.SysUser;
import org.dromara.system.service.ISysUserService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 充值成功回调处理器
 *
 * @author zlj
 * @since 2024/5/16
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class BusinessHandleService {

    private final WxOrderService wxOrderService;
    private final UserFlowingService userFlowingService;
    private final ISysUserService userService;
    private final BusinessConfigService configService;
    private final ScheduledExecutorService scheduledExecutorService;
    private final GoodsService goodsService;
    private final GoodsOrderService orderService;
    private final CouponService couponService;

    /**
     * 支付业务处理
     *
     * @param topUp 订单信息
     */
    public void businessHandle(TopUp topUp) {
        String orderType = topUp.getOrderType();
        String orderJson = topUp.getOrderJson();
        Long userId = topUp.getCreateBy();
        if (ObjectUtil.equals(orderType, "amount")) {
            // 充值类型业务处理
            BigDecimal payerTotal = topUp.getPayerTotal().multiply(BigDecimal.ONE);
            if (StrUtil.isNotBlank(orderJson)) {
                //不为空选择套餐 为空自定义充值
                BusinessConfigVo configVo = configService.queryById(Long.valueOf(orderJson));
                payerTotal = payerTotal.add(new BigDecimal(configVo.getConfigValue1()));
            }
            userFlowingService.addAmount(userId, payerTotal, BusinessConstants.FLOWING_TYPE_TOPUP, null, BusinessConstants.FLOWING_TYPE_AMOUNT);
            scheduledExecutorService.schedule(() -> {
                wxOrderService.uploadShippingInfo(userId, topUp.getTransactionId());
            }, 5, TimeUnit.SECONDS);
        } else if (ObjectUtil.equals(orderType, "vip")) {
            //设置会员等级
            BusinessConfigVo configVo = configService.queryById(Long.valueOf(topUp.getOrderJson()));
            userService.lambdaUpdate().set(SysUser::getVip, configVo.getSortNo()).eq(SysUser::getUserId, userId)
                .lt(SysUser::getVip, configVo.getSortNo()).update();
            scheduledExecutorService.schedule(() -> {
                wxOrderService.uploadShippingInfo(userId, topUp.getTransactionId());
            }, 5, TimeUnit.SECONDS);
        } else if (ObjectUtil.equals(orderType, "goods")) {
            //现金支付订单
            GoodsOrder goodsOrder = orderService.getById(orderJson);
            //增加销量
            goodsService.lambdaUpdate().setSql("num = num + 1").eq(Goods::getGoodsId, goodsOrder.getGoodsId()).update();
            //修改订单
            orderService.lambdaUpdate().set(GoodsOrder::getStatus, ObjectUtil.isNull(goodsOrder.getWaiterId()) ? "2" : "3")
                .set(GoodsOrder::getUpdateTime, new Date())
                .eq(GoodsOrder::getGoodsOrderId, orderJson).update();
            //修改优惠券已使用
            if (ObjectUtil.isNotNull(goodsOrder.getCouponId())) {
                Coupon coupon = couponService.getById(goodsOrder.getCouponId());
                coupon.setStatus("1");
                couponService.updateById(coupon);
            }
            scheduledExecutorService.schedule(() -> {
                wxOrderService.uploadShippingInfo(userId, topUp.getTransactionId());
            }, 5, TimeUnit.SECONDS);
            //发送通知管理员
            SysUser user = userService.getById(userId);
            scheduledExecutorService.schedule(() -> {
                Map<String, String> data = new HashMap<>();
                data.put("thing1", goodsOrder.getName());//商品名称
                data.put("amount5", "￥" + goodsOrder.getPrice());//订单金额
                data.put("thing14", user.getNickName());//购买人
                data.put("date2", DateUtil.format(new Date(), "yyyy年MM月dd日 HH:mm"));//下单时间
                data.put("character_string4", goodsOrder.getGoodsOrderId().toString());//订单编号
                String adminUserId = configService.queryOneByKey("subscribe").getRemark();
                WxSubscribeUtil.sendSubscribeMessage(userService.getById(adminUserId).getOpenid(), "LygIpCmFE69qN9q-CL4FJuHybp1ZepgFhQqSON1G_pc", "pages/index/index", data);
            }, 0, TimeUnit.SECONDS);

            //指定打手的通知打手
            if (ObjectUtil.isNotNull(goodsOrder.getWaiterId())) {
                SysUser waiter = userService.getById(goodsOrder.getWaiterId());
                scheduledExecutorService.schedule(() -> {
                    Map<String, String> data = new HashMap<>();
                    data.put("character_string1", goodsOrder.getGoodsOrderId().toString());//工单编号
                    data.put("short_thing2", user.getNickName());//客户姓名
                    data.put("thing12", goodsOrder.getOneType() + " " + goodsOrder.getName());//客户需求
                    data.put("time6", DateUtil.format(new Date(), "yyyy年MM月dd日 HH:mm"));//日期
                    WxSubscribeUtil.sendSubscribeMessage(waiter.getOpenid(), "u0c4ZyS0QbdYazizcN5Bscy0IUcA_DwOVkRcmw861sc", "pages/index/index", data);
                }, 0, TimeUnit.SECONDS);
            }
        } else if (ObjectUtil.equals(orderType, "ds")) {
            //设置打赏
            //赠与积分(需要扣手续费)
            String giveCc = configService.queryValueByKey("give_cc");
            userFlowingService.addAmount(Long.valueOf(orderJson), topUp.getPayerTotal().multiply(new BigDecimal(giveCc)),
                BusinessConstants.FLOWING_TYPE_GIVE, userId, BusinessConstants.FLOWING_TYPE_AMOUNT);
            scheduledExecutorService.schedule(() -> {
                wxOrderService.uploadShippingInfo(userId, topUp.getTransactionId());
            }, 5, TimeUnit.SECONDS);
        } else if (ObjectUtil.equals(orderType, "shop")) {
            //购物车支付订单
            List<GoodsOrder> list = orderService.lambdaQuery().eq(GoodsOrder::getBuyFlag, orderJson)
                .eq(GoodsOrder::getStatus, "1")
                .eq(GoodsOrder::getCreateBy, userId).list();
            if (CollUtil.isEmpty(list)) {
                return;
            }
            //增加销量
            goodsService.lambdaUpdate().setSql("num = num + 1").in(Goods::getGoodsId, StreamUtils.toList(list, GoodsOrder::getGoodsId)).update();
            //修改订单
            orderService.lambdaUpdate().set(GoodsOrder::getStatus, "2")
                .set(GoodsOrder::getUpdateTime, new Date())
                .eq(GoodsOrder::getBuyFlag, orderJson).update();

            scheduledExecutorService.schedule(() -> {
                wxOrderService.uploadShippingInfo(userId, topUp.getTransactionId());
            }, 5, TimeUnit.SECONDS);
            //发送通知管理员
            SysUser user = userService.getById(userId);
            scheduledExecutorService.schedule(() -> {
                Map<String, String> data = new HashMap<>();
                data.put("thing1", "购物车批量下单");//商品名称
                data.put("amount5", "￥" + topUp.getPayerTotal());//订单金额
                data.put("thing14", user.getNickName());//购买人
                data.put("date2", DateUtil.format(new Date(), "yyyy年MM月dd日 HH:mm"));//下单时间
                data.put("character_string4", list.get(0).getGoodsOrderId().toString());//订单编号
                String adminUserId = configService.queryOneByKey("subscribe").getRemark();
                WxSubscribeUtil.sendSubscribeMessage(userService.getById(adminUserId).getOpenid(), "LygIpCmFE69qN9q-CL4FJuHybp1ZepgFhQqSON1G_pc", "pages/index/index", data);
            }, 0, TimeUnit.SECONDS);
        }
        userService.lambdaUpdate().setSql("all_amount = all_amount +" + topUp.getPayerTotal()).eq(SysUser::getUserId, userId).update();
    }

    /**
     * 退款业务处理
     *
     * @param topUp 订单信息
     */
    public void businessRefundHandle(TopUp topUp) {
        String orderType = topUp.getOrderType();
        String orderJson = topUp.getOrderJson();
        Long userId = topUp.getCreateBy();
        if (ObjectUtil.equals(orderType, "amount")) {
            // 1类型业务处理
            try {
                userFlowingService.addAmount(userId, topUp.getPayerTotal().multiply(new BigDecimal(-1)),
                    BusinessConstants.FLOWING_TYPE_TOPUP, null, BusinessConstants.FLOWING_TYPE_AMOUNT);
            } catch (ServiceException e) {
                scheduledExecutorService.schedule(() -> {
                    WebSocketUtils.sendMessage(UserConstants.SUPER_ADMIN_ID, "用户编号: " + userId + " 退款时余额不足, 请及时处理!");
                }, 0, TimeUnit.SECONDS);
            }
        } else if (ObjectUtil.equals(orderType, "2")) {
            // 2类型业务处理
        }
    }
}
